package com.su.dingtalk.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkcontact_1_0.models.GetUserHeaders;
import com.aliyun.dingtalkcontact_1_0.models.GetUserResponse;
import com.aliyun.dingtalkcontact_1_0.models.GetUserResponseBody;
import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenResponse;
import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.su.dingtalk.config.DingTalkAppConfig;
import com.su.dingtalk.model.DingTalkLoginAuthCallbackReqDTO;
import com.su.dingtalk.service.IDingTalkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;

@Slf4j
@Service
public class DingTalkServiceImpl implements IDingTalkService {

    @Resource
    private DingTalkAppConfig dingTalkAppConfig;

    @Override
    public String genAuthorize() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("redirect_uri", dingTalkAppConfig.getRedirectUri());
        map.put("response_type", dingTalkAppConfig.getResponseType());
        map.put("client_id", dingTalkAppConfig.getAppKey());
        map.put("scope", dingTalkAppConfig.getScope());
        map.put("prompt", dingTalkAppConfig.getPrompt());
        log.info("请求参数为:" + JSONUtil.toJsonStr(map));
        String response = HttpUtil.toParams(map);
        log.info("相应参数为:" + JSONUtil.toJsonStr(response));
        return response;
    }


    @Override
    public String callback(String source, DingTalkLoginAuthCallbackReqDTO req) {
        //1、获取 accesstoken
        GetUserTokenResponseBody body = null;
        try {
            body = getAccessToken(req.getAuthCode());
        } catch (Exception e) {
            log.error("获取 accesstoken 失败", e);
        }
        assert body != null;
        String accessToken = body.getAccessToken();
        try {
            // 获取用户通讯录个人信息，如需获取当前授权人的信息，unionId参数必须传me
            return contactUsers(accessToken, "me");
        } catch (Exception e) {
            log.error("获取用户通讯录个人信息 失败", e);
        }
        return null;
    }

    /**
     * 获取访问凭证，使用 authCode 和应用的信息，调用获取用户token接口得到 access_token
     *
     * @param authCode
     * @return
     * @throws Exception
     */
    public GetUserTokenResponseBody getAccessToken(String authCode) throws Exception {
        com.aliyun.dingtalkoauth2_1_0.Client client = dingtalkoauth2_1_0();
        GetUserTokenRequest getUserTokenRequest = new GetUserTokenRequest()
                .setClientId(dingTalkAppConfig.getAppKey())
                .setClientSecret(dingTalkAppConfig.getAppSecret())
                .setCode(authCode)
                .setGrantType(dingTalkAppConfig.getGrantType());
        try {
            GetUserTokenResponse userToken = client.getUserToken(getUserTokenRequest);
            log.info("userToken" + JSONObject.toJSONString(userToken));
            return userToken.getBody();
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        }
        return null;
    }


    /**
     * 获取用户通讯录个人信息
     *
     * @param accessToken
     * @param unionId
     * @throws Exception
     */
    public String contactUsers(String accessToken, String unionId) throws Exception {
        com.aliyun.dingtalkcontact_1_0.Client client = dingtalkcontact_1_0();
        GetUserHeaders getUserHeaders = new GetUserHeaders();
        getUserHeaders.xAcsDingtalkAccessToken = accessToken;
        try {
            GetUserResponse userWithOptions = client.getUserWithOptions(unionId, getUserHeaders, new RuntimeOptions());
            GetUserResponseBody body = userWithOptions.getBody();
            return JSONObject.toJSONString(body);
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        }
        return "";
    }

    public static com.aliyun.dingtalkcontact_1_0.Client dingtalkcontact_1_0() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkcontact_1_0.Client(config);
    }

    public static com.aliyun.dingtalkoauth2_1_0.Client dingtalkoauth2_1_0() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

}
